package com.hk.service.business;

import cn.hutool.core.map.MapUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.LongAdder;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

/**
 * @author: dpb
 * @date: 2022/11/28
 */
@Service
@Slf4j
public class ConcurrencyBusiness {

    //线程数量
    private static int THREAD_COUNT = 10;

    //总数
    private static int ITEM_COUNT = 1000;

    //循环次数
    private static int LOOP_COUNT = 10;

    private static int THREAD_COUNT_2 = 10;

    private static int ITEM_COUNT_2 = 10;


    public Map<String, Long> normaluse() throws Exception {
        ConcurrentHashMap<String, Long> freqs = new ConcurrentHashMap<>(ITEM_COUNT_2);
        ForkJoinPool forkJoinPool = new ForkJoinPool(THREAD_COUNT_2);
        forkJoinPool.execute(()-> IntStream.rangeClosed(1, LOOP_COUNT).parallel().forEach(i -> {
            //获取得一个随机Key
            String key = "item" + ThreadLocalRandom.current().nextInt(ITEM_COUNT_2);
//            log.info("生成的key:{}", key);
            synchronized (freqs) {
                if (freqs.containsKey(key)) {
                    //key存在则+1
                    freqs.put(key, freqs.get(key) + 1);
                } else {
                    //key不存在则初始化为1
                    freqs.put(key, 1L);
                }
            }
        }));
        forkJoinPool.shutdown();
        forkJoinPool.awaitTermination(1, TimeUnit.HOURS);
//        log.info("freqs出现的次数:{}", freqs.size());
        return freqs;
    }


    public  Map<String, Long> goodUse() throws Exception {
        ConcurrentHashMap<String, LongAdder> freqs = new ConcurrentHashMap<>(ITEM_COUNT_2);
        ForkJoinPool forkJoinPool = new ForkJoinPool(THREAD_COUNT_2);
        forkJoinPool.execute(() -> IntStream.rangeClosed(1, LOOP_COUNT).parallel().forEach(i -> {
                    String key = "item" + ThreadLocalRandom.current().nextInt(ITEM_COUNT_2);
                    freqs.computeIfAbsent(key, k -> new LongAdder()).increment();
                }
        ));

        forkJoinPool.shutdown();
        forkJoinPool.awaitTermination(1, TimeUnit.HOURS);
        Map<String, Long> map = freqs.entrySet().stream()
                .collect(Collectors.toMap(
                        e -> e.getKey(),
                        e -> e.getValue().longValue())
                );

        return map;
    }


}
